<style scoped lang="scss">
.main {
  padding: 2vh;
  background-color: #2d3748;
}
.n-card {
  width: 20vw;
}
</style>

<template>
  <div class="main">
    <n-flex justify="space-around" size="large">
      <div>
        <n-scrollbar style="max-height: 96vh">
          <canvas
            ref="canvas"
            width="1371"
            height="1920"
            :style="canvasStyle"
            @mousedown="onMouseDown"
            @mousemove="onMouseMove"
            @mouseup="onMouseUp"
            @mouseleave="onMouseLeave"
          ></canvas>
        </n-scrollbar>
      </div>
      <div>
        <n-card>
          <n-switch v-model:value="isDrawingEnabled" :rail-style="railStyle">
            <template #checked>开启绘画</template>
            <template #unchecked>调整绘画</template>
          </n-switch>
          <n-space vertical>
            <n-slider v-model:value="canvasValue" :step="1" />
          </n-space>
        </n-card>
        <n-card style="margin-top: 3vh">
          <n-pagination
            mt5vh
            v-model:page="page"
            :page-count="imageList.page.total_page"
            @update:page="onPageChange"
          />
        </n-card>
      </div>
    </n-flex>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue';
import { getPdfImages, type PdfImagesResponse } from '@/api/image';
import type { CSSProperties } from 'vue';

const canvasValue = ref(100);
const props = defineProps<{ id: string }>();
const isDrawingEnabled = ref(true); // true: 绘画模式，false: 调整模式
const railStyle = ({ focused, checked }: { focused: boolean; checked: boolean }): CSSProperties => {
  const style: CSSProperties = {};
  if (checked) {
    style.background = '#2080f0';
    if (focused) {
      style.boxShadow = '0 0 0 2px #2080f040';
    }
  } else {
    style.background = '#d03050';
    if (focused) {
      style.boxShadow = '0 0 0 2px #d03050';
    }
  }
  return style;
};

const pdfId = Number(decodeURIComponent(props.id));
const page = ref(1);
const imageList = ref<PdfImagesResponse>({ data: [], page: { current_page: 1, total_page: 1 } });
const canvas = ref<HTMLCanvasElement | null>(null);
const isDrawing = ref(false); // 存储绘制状态
const rectangleStartX = ref(0); // 矩形起始位置 X
const rectangleStartY = ref(0); // 矩形起始位置 Y
const currentX = ref(0); // 当前鼠标位置 X
const currentY = ref(0); // 当前鼠标位置 Y
const rectangles = ref<{ x: number; y: number; width: number; height: number }[]>([]); // 用于存储所有矩形
const currentRectIndex = ref<number | null>(null); // 当前正在调整的矩形索引
const offsetX = ref(0); // 鼠标相对矩形的位置 X
const offsetY = ref(0); // 鼠标相对矩形的位置 Y

const onPageChange = (newPage: number) => {
  page.value = newPage;
};

const canvasStyle = computed(() => {
  const imageUrl = imageList.value.data.length > 0 ? imageList.value.data[0].url : '';
  return {
    backgroundImage: `url('${imageUrl}')`,
    transform: `scale(${canvasValue.value / 100})`,
    transformOrigin: 'top center',
  };
});

const fetchData = async (pageNumber: number) => {
  try {
    const response = await getPdfImages(pdfId, pageNumber);
    imageList.value = response.data;

    // 动态设置 canvas 的大小
    const image = new Image();
    image.src = imageList.value.data[0]?.url || '';
    image.onload = () => {
      const canvasElement = canvas.value;
      if (canvasElement) {
        canvasElement.width = image.width;
        canvasElement.height = image.height;
        onCanvasDraw(); // 重新绘制画布
      }
    };
  } catch (error) {
    console.error('获取 PDF 列表时出错:', error);
  }
};

const drawRectangle = (ctx: CanvasRenderingContext2D, rectangle: { x: number; y: number; width: number; height: number }) => {
  ctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; // 设置长方形颜色
  ctx.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height); // 绘制矩形
};

const clearCanvas = (ctx: CanvasRenderingContext2D) => {
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // 清空画布
};

const onCanvasDraw = () => {
  const canvasElement = canvas.value;
  if (canvasElement) {
    const ctx = canvasElement.getContext('2d');
    if (ctx) {
      clearCanvas(ctx); // 每次重绘前清空画布
      rectangles.value.forEach(rectangle => {
        drawRectangle(ctx, rectangle); // 绘制所有保存的矩形
      });
      // 在绘制模式下，绘制当前矩形
      if (isDrawing.value) {
        drawRectangle(ctx, {
          x: rectangleStartX.value,
          y: rectangleStartY.value,
          width: currentX.value - rectangleStartX.value,
          height: currentY.value - rectangleStartY.value,
        });
      }
    } else {
      console.error('无法获取 2D 上下文');
    }
  } else {
    console.error('Canvas 元素为 null');
  }
};

// 鼠标按下事件
const onMouseDown = (event: MouseEvent) => {
  const mouseX = event.offsetX;
  const mouseY = event.offsetY;

  if (isDrawingEnabled.value) {
    // 绘画模式
    isDrawing.value = true; // 启用绘画
    rectangleStartX.value = mouseX;
    rectangleStartY.value = mouseY;
  } else {
    // 调整模式
    const rectIndex = rectangles.value.findIndex(rect =>
      mouseX >= rect.x && mouseX <= rect.x + rect.width && mouseY >= rect.y && mouseY <= rect.y + rect.height
    );

    if (rectIndex !== -1) {
      currentRectIndex.value = rectIndex; // 保存正在调整的矩形索引
      offsetX.value = mouseX - rectangles.value[rectIndex].x; // 计算鼠标相对位置
      offsetY.value = mouseY - rectangles.value[rectIndex].y;
    }
  }
};

// 鼠标移动事件
const onMouseMove = (event: MouseEvent) => {
  if (isDrawingEnabled.value && isDrawing.value) {
    // 绘画模式
    currentX.value = event.offsetX;
    currentY.value = event.offsetY;
    onCanvasDraw(); // 更新画布
  } else if (currentRectIndex.value !== null) {
    // 调整模式
    const index = currentRectIndex.value;
    const rectangle = rectangles.value[index];
    rectangle.x = event.offsetX - offsetX.value; // 更新矩形位置
    rectangle.y = event.offsetY - offsetY.value;
    onCanvasDraw(); // 更新画布
  }
};

// 鼠标抬起事件
const onMouseUp = () => {
  if (isDrawingEnabled.value && isDrawing.value) {
    isDrawing.value = false; // 结束绘制模式
    const width = currentX.value - rectangleStartX.value;
    const height = currentY.value - rectangleStartY.value;

    // 保存当前矩形到 rectangles 数组
    if (width >= 50 && height >= 50) {
      rectangles.value.push({
        x: rectangleStartX.value,
        y: rectangleStartY.value,
        width,
        height,
      });
    }
  }
  currentRectIndex.value = null; // 结束调整
};

// 鼠标离开事件
const onMouseLeave = () => {
  if (isDrawing.value) {
    isDrawing.value = false; // 结束绘制模式
  }
  currentRectIndex.value = null; // 结束调整
};

watch(page, (newPage) => {
  fetchData(newPage);
  onCanvasDraw(); // 在每次页面更改时绘制
});

onMounted(() => {
  fetchData(page.value);
});
</script>